var icon_switch_url = 'imgs/switch.png';
var icon_cabinet_url = 'imgs/cabinet.png';
var icon_device_url = 'imgs/device.png';
var icon_odf_url = 'imgs/odf.png';
//端口
var Port = {
    fontFamily:'Courier New',
    fontSize:22,
    fontColor: '#ffffff',
    width: 160,//接口宽度
    height:120,//接口高度
    lugWidth:30,//突出部宽度
    lugHeight:30,//突出部高度
    lugMarginLeft:2,
    lampstandWidth:20,//底座宽度
    lampstandHeight:50,//底座高度
    lineWidth:2,//线宽
    borderHorSpace:6,//线框距水平边沿间隔
    borderVerSpace:4,//现况剧垂直边沿间隔
    arrowColor:'#cc37eb',//箭头颜色
    createNew: function(if_id,of_id,name){//接收接口ID，发送接口ID，名称
        var port = {};
        port.x=0;
        port.y=0;
        port.if_id = if_id;
        port.of_id = of_id;
        port.name = name;
        port.direct = 'left';
        port.bodyBackground = '#a1c4c0';
        port.connectLines = [];
        port.getOutConnectorPos = function(){
            var x = 0, y = 0;
            if(port.direct == 'left'){
                y = this.y + Port.height * 3 / 4;
                x = this.x - 2;
            }else{
                y = this.y + Port.height * 1 / 4;
                x = this.x + Port.width + 2;
            }
            return {x:x,y:y};
        };
        port.getInConnectorPos = function(){
            var x = 0, y = 0;
            if(port.direct == 'left'){
                y = this.y + Port.height * 1 / 4;
                x = this.x - 2;
                x -= Path.lineWidth;
            }else{
                y = this.y + Port.height * 3 / 4;
                x = this.x + Port.width + 2;
                x += Path.lineWidth;
            }
            return {x:x,y:y};
        };
        port.draw = function(canvas){
            //画底色
            canvas.fillStyle = this.bodyBackground;
            canvas.fillRect(this.x, this.y, Port.width,Port.height);
            //画接口
            var interfaceBackground = '#609bc3';//突出部颜色
            var borderColor = '#ffffff';//围框颜色
            if(port.direct == 'left'){
                //画突出部1
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x + Port.lugMarginLeft, this.y + (Port.height - 2) / 4 - Port.lugHeight / 2, Port.lugWidth,Port.lugHeight);
                //画底座1
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x + Port.lugMarginLeft + Port.lugWidth, this.y + (Port.height - 2) / 4 - Port.lampstandHeight / 2, Port.lampstandWidth,Port.lampstandHeight);
                //画突出部2
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x + Port.lugMarginLeft, this.y + (Port.height - 2) * 3 / 4 - Port.lugHeight / 2, Port.lugWidth,Port.lugHeight);
                //画底座2
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x + Port.lugMarginLeft + Port.lugWidth, this.y + (Port.height - 2) * 3 / 4 - Port.lampstandHeight / 2, Port.lampstandWidth,Port.lampstandHeight);
                //画间隔线
                canvas.beginPath();
                canvas.strokeStyle = interfaceBackground;
                canvas.lineWidth=Port.lineWidth;
                canvas.moveTo(this.x + Port.lugMarginLeft,this.y + Port.height / 2 - Port.lineWidth / 2);
                canvas.lineTo(this.x + Port.lugMarginLeft + Port.lugWidth + Port.lampstandWidth,this.y + Port.height / 2 - Port.lineWidth / 2);
                canvas.stroke();
                //画围框1
                canvas.beginPath();
                canvas.strokeStyle = borderColor;
                canvas.lineWidth=Port.lineWidth;
                canvas.moveTo(this.x + Port.borderHorSpace + Port.lugWidth,this.y + (Port.height - 2) / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x + Port.borderHorSpace,this.y + (Port.height - 2) / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x + Port.borderHorSpace,this.y + (Port.height - 2) / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.lineTo(this.x + Port.borderHorSpace + Port.lugWidth,this.y + (Port.height - 2) / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.stroke();
                //画围框2
                canvas.beginPath();
                canvas.strokeStyle = borderColor;
                canvas.lineWidth=Port.lineWidth;
                canvas.moveTo(this.x + Port.borderHorSpace + Port.lugWidth,this.y + (Port.height - 2) * 3 / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x + Port.borderHorSpace,this.y + (Port.height - 2) * 3 / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x + Port.borderHorSpace,this.y + (Port.height - 2) * 3 / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.lineTo(this.x + Port.borderHorSpace + Port.lugWidth,this.y + (Port.height - 2) * 3 / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.stroke();
                //画箭头1
                drawArrow(canvas,this.x + Port.borderHorSpace + Port.lineWidth * 2, this.y + (Port.height - 2) / 4, this.x + Port.lugWidth, this.y + (Port.height - 2) / 4, 30, 10, Port.lineWidth, Port.arrowColor);
                //画箭头2
                drawArrow(canvas, this.x + Port.lugWidth, this.y + (Port.height - 2) * 3 / 4,this.x + Port.borderHorSpace + Port.lineWidth * 2, this.y + (Port.height - 2) * 3 / 4, 30, 10, Port.lineWidth, Port.arrowColor);
                //画出名字
                canvas.font = Port.fontSize + "px " + Port.fontFamily;
                canvas.fillStyle = Port.fontColor;
                canvas.textAlign="left";
                canvas.fillText(this.name,this.x + Port.lugMarginLeft + Port.lugWidth + Port.lampstandWidth + Port.lugMarginLeft, this.y + (Port.height + Port.fontSize) / 2 - 2 , Port.width - Port.lugMarginLeft - Port.lugWidth - Port.lampstandWidth - Port.lugMarginLeft);
            }else{
                //画突出部1
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x + Port.width - Port.lugWidth - Port.lugMarginLeft, this.y + (Port.height - 2) / 4 - Port.lugHeight / 2, Port.lugWidth,Port.lugHeight);
                //画底座1
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x  + Port.width - Port.lugWidth - Port.lugMarginLeft - Port.lampstandWidth, this.y + (Port.height - 2) / 4 - Port.lampstandHeight / 2, Port.lampstandWidth,Port.lampstandHeight);
                //画突出部2
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x + Port.width - Port.lugWidth - Port.lugMarginLeft, this.y + (Port.height - 2) * 3 / 4 - Port.lugHeight / 2, Port.lugWidth,Port.lugHeight);
                //画底座2
                canvas.fillStyle = interfaceBackground;
                canvas.fillRect(this.x  + Port.width - Port.lugWidth - Port.lugMarginLeft - Port.lampstandWidth, this.y + (Port.height - 2) * 3 / 4 - Port.lampstandHeight / 2, Port.lampstandWidth,Port.lampstandHeight);
                //画间隔线
                canvas.beginPath();
                canvas.strokeStyle = interfaceBackground;
                canvas.lineWidth=Port.lineWidth;
                canvas.moveTo(this.x + Port.width - Port.lugMarginLeft,this.y + Port.height / 2 - Port.lineWidth / 2);
                canvas.lineTo(this.x + Port.width - Port.lugMarginLeft - Port.lugWidth - Port.lampstandWidth,this.y + Port.height / 2 - Port.lineWidth / 2);
                canvas.stroke();
                //画围框1
                canvas.beginPath();
                canvas.strokeStyle = borderColor;
                canvas.lineWidth=Port.lineWidth;
                canvas.moveTo(this.x + Port.width - Port.borderHorSpace - Port.lugWidth,this.y + (Port.height - 2) / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x  + Port.width -  Port.borderHorSpace,this.y + (Port.height - 2) / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x  + Port.width -  Port.borderHorSpace,this.y + (Port.height - 2) / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.lineTo(this.x + Port.width - Port.borderHorSpace - Port.lugWidth,this.y + (Port.height - 2) / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.stroke();
                //画围框2
                canvas.beginPath();
                canvas.strokeStyle = borderColor;
                canvas.lineWidth=Port.lineWidth;
                canvas.moveTo(this.x + Port.width - Port.borderHorSpace - Port.lugWidth,this.y + (Port.height - 2) * 3 / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x  + Port.width -  Port.borderHorSpace,this.y + (Port.height - 2) * 3 / 4 - Port.lugHeight / 2 + Port.borderVerSpace);
                canvas.lineTo(this.x  + Port.width -  Port.borderHorSpace,this.y + (Port.height - 2) * 3 / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.lineTo(this.x + Port.width - Port.borderHorSpace - Port.lugWidth,this.y + (Port.height - 2) * 3 / 4 + Port.lugHeight / 2 -Port.borderVerSpace);
                canvas.stroke();
                //画箭头1
                drawArrow(canvas,this.x + Port.width - Port.lugWidth - Port.borderHorSpace + Port.lineWidth , this.y + (Port.height - 2) / 4, this.x + Port.width - Port.borderHorSpace - Port.lineWidth * 3, this.y + (Port.height - 2) / 4, 30, 10, Port.lineWidth, Port.arrowColor);
                //画箭头2
                drawArrow(canvas, this.x + Port.width - Port.borderHorSpace - Port.lineWidth * 3, this.y + (Port.height - 2) * 3 / 4,this.x + Port.width - Port.lugWidth - Port.borderHorSpace + Port.lineWidth , this.y + (Port.height - 2) * 3 / 4, 30, 10, Port.lineWidth, Port.arrowColor);
                //画出名字
                canvas.font = Port.fontSize + "px " + Port.fontFamily;
                canvas.fillStyle = Port.fontColor;
                canvas.textAlign="left";
                canvas.fillText(this.name,this.x + Port.lugMarginLeft, this.y + (Port.height + Port.fontSize) / 2 - 2 , Port.width - Port.lugMarginLeft - Port.lugWidth - Port.lampstandWidth - Port.lugMarginLeft);
            }
        }
        return port;
    }
};
//交换机，高度由端口模块数量决定
var Switch = {
    headerHeight: 40,//标题栏高度
    width:340,//默认宽度
    arrowLength:100,//箭头长度
    headerFontFamily:'Courier New',
    headerFontSize:16,
    headerFontColor: '#ffffff',
    headerBackground: '#04a69b',//标题栏底色
    bodyBackground:'#cdcdcd',//内部容器底色
    portBackground: '#a1c4c0',//端口模块底色
    portVerSpace:4,//端口模块竖向间隔
    portVerSpaceBackground:'#8eafb8',//端口模块竖向间隔底色
    createNew: function(id,name){
        var _switch = {};
        _switch.x=0;
        _switch.y=0;
        _switch.width=Switch.width;
        _switch.id = id;
        _switch.name = name;
        _switch.ports = [];
        _switch.portsForDraw = [];
        _switch.draw = function(canvas){
            Switch.draw(this, canvas);
        };
        _switch.addPort = function(port){
            _switch.ports.push(port);
        };
        _switch.getPort = function(port_id){
            for(var k in this.ports){
                if(_switch.ports[k].if_id == port_id || _switch.ports[k].of_id == port_id){
                    return _switch.ports[k];
                }
            }
            return null;
        };
        _switch.initPort = function(portListJson){
            //{"count": 44,"list": [{"BOARD_ID": 6,"DIRECTION": "Tx","NAME": "A","PLUG": "ST","PORT_ID": 83},
            portListJson.list.sort(function(a,b)
            {
                if( a.NAME > b.NAME){
                    return 1;
                }
                if( a.NAME < b.NAME){
                    return -1;
                }
                return 0;
            });
            for(var i = 0; i < portListJson.list.length; i++){
                var curP = portListJson.list[i];
                var nextP = null;
                if(i + 1 < portListJson.list.length){
                    if(curP.NAME == portListJson.list[i + 1].NAME){
                        nextP = portListJson.list[i + 1];
                        i += 1;
                    }
                }
                var p = null;
                if(curP.DIRECTION == 'Rx'){//Rx-接收，Tx-发送
                    if(nextP != null){
                        p = Port.createNew(curP.PORT_ID, nextP.PORT_ID, curP.NAME);
                    }else{
                        p = Port.createNew(curP.PORT_ID, null, curP.NAME);
                    }
                }else{
                    if(nextP != null){
                        p = Port.createNew(nextP.PORT_ID, curP.PORT_ID, curP.NAME);
                    }else{
                        p = Port.createNew(null, curP.PORT_ID, curP.NAME);
                    }
                }
                switchObject.addPort(p);
            }
        };
        _switch.addConnectDevice = function(connectLines){
            /*[
                {
                    port_start:{
                        "PORT_DIRECTION": c.PORT1_DIRECTION,
                        "PORT_ID": c.PORT1_ID,
                        "PORT_NAME": c.PORT1_NAME,
                        "PORT_PLUG": c.PORT1_PLUG,
                        "UNIT_CLASS": c.UNIT1_CLASS,
                        "UNIT_DESC": c.UNIT1_DESC,
                        "UNIT_ID": c.UNIT1_ID,
                        "UNIT_IED": "",
                    },
                    type:c.TYPE,
                    port_end:{
                        "PORT_DIRECTION": c.PORT2_DIRECTION,
                        "PORT_ID": c.PORT2_ID,
                        "PORT_NAME": c.PORT2_NAME,
                        "PORT_PLUG": c.PORT2_PLUG,
                        "UNIT_CLASS": c.UNIT2_CLASS,
                        "UNIT_DESC": c.UNIT2_DESC,
                        "UNIT_ID": c.UNIT2_ID,
                        "UNIT_IED": "",
                    },
                }
            ]*/
            //连接线去重
            var theConnectLines = [];
            for(var i=0;i<connectLines.length;i++){
                var c = connectLines[i];
                var newItem = null;
                if(c.port_start.UNIT_ID == this.id){
                    newItem = {
                        port_start:c.port_start,
                        type:c.type,
                        port_end:c.port_end
                    };
                }else{
                    newItem = {
                        port_start:c.port_end,
                        type:c.type,
                        port_end:c.port_start
                    };
                }
                var hasAdded = false;
                for(var k in theConnectLines){
                    var d = theConnectLines[k];
                    if(d.type == newItem.type && 
                    d.port_start.PORT_ID == newItem.port_start.PORT_ID &&
                    d.port_start.PORT_DIRECTION == newItem.port_start.PORT_DIRECTION &&
                    d.port_end.PORT_ID == newItem.port_end.PORT_ID &&
                    d.port_end.PORT_DIRECTION == newItem.port_end.PORT_DIRECTION){
                        hasAdded = true;
                        break;
                    }
                }
                if(!hasAdded){
                    theConnectLines.push(newItem);
                }
            }
            //每个接口连接线判断
            for(var i=0;i<this.ports.length;i++){
                var p = this.ports[i];
                //找和这个接口相关的连接线
                for(var k in theConnectLines){
                    if(theConnectLines[k].port_start.PORT_ID == p.if_id ||
                    theConnectLines[k].port_start.PORT_ID == p.of_id){
                        p.connectLines.push(theConnectLines[k]);
                    }
                }
            }
            //为每个接口和对应的装置生成绘制对象
            for(var i=0;i<this.ports.length;i++){
                var port = this.ports[i];
                var hasUsedPortId = [];
                for(var k in port.connectLines){
                    var liner = port.connectLines[k];
                    if(hasUsedPortId.hasOwnProperty(liner.type + liner.port_end.PORT_ID)){
                        continue;
                    }
                    port.name = liner.port_start.PORT_NAME;
                    hasUsedPortId[liner.type + liner.port_end.PORT_ID] = true;
                    var sp = Port.createNew(port.if_id, port.of_id, port.name);
                    var d = Device.createNew(liner.port_end.UNIT_ID, liner.port_end.UNIT_DESC);
                    d.info = liner.port_end;
                    sp.device = d;
                    sp.device.paths = [];
                    //查看有没有共用此端口的连接线
                    var linerSamePort = null;
                    for(var k2 in port.connectLines){
                        var liner2 = port.connectLines[k2];
                        if(hasUsedPortId.hasOwnProperty(liner2.type + liner2.port_end.PORT_ID)){
                            continue;
                        }
                        if(liner.port_end.UNIT_ID == liner2.port_end.UNIT_ID &&
                        liner.port_end.PORT_NAME == liner2.port_end.PORT_NAME &&
                        liner.port_end.PORT_DIRECTION != liner2.port_end.PORT_DIRECTION &&
                        liner.type == liner2.type){
                            linerSamePort = liner2;
                            break; 
                        }
                    }
                    var dp = Port.createNew(1, 2, liner.port_end.PORT_NAME);
                    sp.device.port = dp;
                    //插入连接线
                    var testLiner = liner;
                    if(testLiner.port_end.PORT_DIRECTION == "Rx"){
                        var p = Path.createNew(1, dp, sp, testLiner.type);
                        sp.device.paths.push(p);
                    } else if(testLiner.port_end.PORT_DIRECTION == "Tx"){
                        var p = Path.createNew(1, sp, dp, testLiner.type);
                        sp.device.paths.push(p);
                    } else if(testLiner.port_end.PORT_DIRECTION == "RT"){
                        if(testLiner.port_start.PORT_DIRECTION == "Rx"){
                            var p = Path.createNew(1, sp, dp, testLiner.type);
                            sp.device.paths.push(p);
                        } else if(testLiner.port_start.PORT_DIRECTION == "Tx"){
                            var p = Path.createNew(1, dp, sp, testLiner.type);
                            sp.device.paths.push(p);
                        }
                    }
                    //\插入连接线
                    if(linerSamePort != null){
                        hasUsedPortId[linerSamePort.type + linerSamePort.port_end.PORT_ID] = true;
                        //插入连接线
                        var testLiner = linerSamePort;
                        if(testLiner.port_end.PORT_DIRECTION == "Rx"){
                            var p = Path.createNew(1, dp, sp, testLiner.type);
                            sp.device.paths.push(p);
                        } else if(testLiner.port_end.PORT_DIRECTION == "Tx"){
                            var p = Path.createNew(1, sp, dp, testLiner.type);
                            sp.device.paths.push(p);
                        } else if(testLiner.port_end.PORT_DIRECTION == "RT"){
                            if(testLiner.port_start.PORT_DIRECTION == "Rx"){
                                var p = Path.createNew(1, sp, dp, testLiner.type);
                                sp.device.paths.push(p);
                            } else if(testLiner.port_start.PORT_DIRECTION == "Tx"){
                                var p = Path.createNew(1, dp, sp, testLiner.type);
                                sp.device.paths.push(p);
                            }
                        }
                        //\插入连接线
                    }
                    this.portsForDraw.push(sp);
                }
            }
        };
        _switch.getTotalWidth = function(){
            return this.width + 2 * (Switch.arrowLength + Device.width + Port.width);
        };
        _switch.getTotalHeight = function(){
            return Switch.headerHeight + Port.height * Math.ceil(this.portsForDraw.length / 2) + Switch.portVerSpace * Math.ceil(this.portsForDraw.length / 2 - 1);
        };
        _switch.getPortByPoint = function(x ,y){
            for(var i=0;i<this.portsForDraw.length;i++){
                //1.点击的是不是此交换机接口？
                var p = this.portsForDraw[i];
                //上半部分是of_id
                if(p.x < x && p.x + Port.width > x && p.y < y && p.y + Port.height / 2 > y){
                    if(p.of_id != null && p.of_id != undefined){
                        return {
                            UNIT_ID : this.id,
                            PORT_ID : p.of_id,
                            TYPE : 'PORT'
                        }
                    }
                    return null;
                }
                //下半部分是if_id
                if(p.x < x && p.x + Port.width > x && p.y + Port.height / 2 < y && p.y + Port.height > y){
                    if(p.if_id != null && p.if_id != undefined){
                        return {
                            UNIT_ID : this.id,
                            PORT_ID : p.if_id,
                            TYPE : 'PORT'
                        }
                    }
                    return null;
                }
                //2.点击的是不是与此端口连接的装置端口？
                var d = p.device;
                var p = p.device.port;
                //上半部分是of_id
                if(p.x < x && p.x + Port.width > x && p.y < y && p.y + Port.height / 2 > y){
                    if(p.of_id != null && p.of_id != undefined){
                        return {
                            UNIT_ID : d.id,
                            PORT_ID : p.of_id,
                            TYPE : 'PORT'
                        }
                    }
                    return null;
                }
                //下半部分是if_id
                if(p.x < x && p.x + Port.width > x && p.y + Port.height / 2 < y && p.y + Port.height > y){
                    if(p.if_id != null && p.if_id != undefined){
                        return {
                            UNIT_ID : d.id,
                            PORT_ID : p.if_id,
                            TYPE : 'PORT'
                        }
                    }
                    return null;
                }
            }
            return null;
        }
        return _switch;
    },
    draw: function(obj,canvas){
        //绘制标题栏
        canvas.fillStyle = Switch.headerBackground;
        canvas.fillRect(obj.x,obj.y,obj.width,Switch.headerHeight);
        //小图标
        var img = new Image();    
        img.src = icon_switch_url;
        if(img.complete){
            canvas.drawImage(img,obj.x + 5, obj.y + 5,Switch.headerHeight - 10 ,Switch.headerHeight - 10);
        }else{
            img.onload = function(){
                canvas.drawImage(img,obj.x + 5, obj.y + 5,Switch.headerHeight - 10 ,Switch.headerHeight - 10);
            }
        }
        //标题
        canvas.font = Switch.headerFontSize + "px " + Switch.headerFontFamily;
        canvas.fillStyle = Switch.headerFontColor;
        canvas.textAlign="center";
        canvas.fillText(obj.name,obj.x + Switch.headerHeight + (obj.width - Switch.headerHeight) / 2, obj.y + (Switch.headerHeight + Switch.headerFontSize) / 2 -2,obj.width - Switch.headerHeight - 10);
        
        //绘制接口容器
        canvas.fillStyle = Switch.bodyBackground;
        canvas.fillRect(obj.x, obj.y + Switch.headerHeight, obj.width,Math.ceil(obj.portsForDraw.length / 2) * Port.height + (Math.ceil(obj.portsForDraw.length / 2) - 1) * Switch.portVerSpace);
        //绘制内部接口
        var row = 0;
        var column = 0;
        for(var i=0;i<obj.portsForDraw.length;i++){
            port = obj.portsForDraw[i];
            port.bodyBackground = Switch.portBackground;
            port.x = column == 0 ? obj.x : obj.x + obj.width - Port.width;
            port.y = obj.y + Switch.headerHeight + row * (Port.height + Switch.portVerSpace);
            //不是第一行，画间隔线
            if(row > 0){
                canvas.fillStyle = Switch.portVerSpaceBackground;
                canvas.fillRect(port.x, port.y - Switch.portVerSpace, Port.width,Switch.portVerSpace);
            }
            if(column == 0){
                port.direct = 'left';
            }else{
                port.direct = 'right';
            }
            //画当前接口
            port.draw(canvas);
            //画与接口连接的装置
            if(port.direct == 'left'){
                port.device.x = port.x - Device.width - Port.width - Switch.arrowLength;
                port.device.y = port.y;
                port.device.port.direct = 'right';
            }else{
                port.device.x = port.x + Port.width + Port.width + Switch.arrowLength;
                port.device.y = port.y;
                port.device.port.direct = 'left';
            }
            Device.draw(port.device,canvas);
            //画连接线
            for(var k in port.device.paths){
                var p = port.device.paths[k];
                Path.draw(p, canvas);
            }

            if(column > 0){
                column = 0;
                row += 1;
            }else{
                column++;
            }
        }
    }
};
//其他装置
var Device = {
    headerFontFamily:'Courier New',
    headerFontSize:22,
    headerFontColor: '#ffffff',
    width:180,
    headerBackground: '#01a59a',//标题栏底色
    bodyBackground:'#6194cd',//内部容器底色
    portBackground: '#3f7d78',//端口模块底色
    portVerSpace:4,//端口模块竖向间隔
    portVerSpaceBackground:'#8eafb8',//端口模块竖向间隔底色
    createNew: function(id,name){
        var device = {};
        device.x=0;
        device.y=0;
        device.width=Device.width;
        device.id = id;
        device.name = name;
        device.ports = [];
        device.deviceIconWidth = 20;
        device.deviceIconHeight = 50;
        device.draw = function(canvas){
            Device.draw(this, canvas);
        };
        device.tryInsertPortByInfo = function(portinfo){
            /*{
                PORT_ID:"",
                NAME:"",
                PLUG:"",
                DIRECTION:""
            }*/
            var thePort = null;
            for(var k in this.ports){
                var p = this.ports[k];
                if(p.NAME == portinfo.NAME){
                    thePort = p;
                    break;
                }
            }
            if(portinfo.DIRECTION == 'RX'){//接收
                if(thePort == null){
                    thePort = Port.createNew(portinfo.PORT_ID,null,portinfo.NAME);
                    thePort.NAME = portinfo.NAME;
                    this.ports.push(thePort);
                }
                thePort.if_id = portinfo.PORT_ID;
            } else {//发送
                if(thePort == null){
                    thePort = Port.createNew(null,portinfo.PORT_ID,portinfo.NAME);
                    thePort.NAME = portinfo.NAME;
                    this.ports.push(thePort);
                }
                thePort.of_id = portinfo.PORT_ID;
            }
        };
        return device;
    },
    draw: function(obj,canvas){
        if(obj.ports.length < 1){
            obj.height = Port.height;
        }else{
            obj.height = obj.ports.length * Port.height + (obj.ports.length - 1) * Device.portVerSpace;
        }
        //绘制主体色
        canvas.fillStyle = Device.headerBackground;
        canvas.fillRect(obj.x,obj.y + 2,obj.width,obj.height - 4);
        //小图标
        var img = new Image();    
        img.src = icon_device_url;
        if(obj.info.UNIT_CLASS == 'SWITCH'){
            img.src = icon_switch_url;
        }else if(obj.info.UNIT_CLASS == 'ODF'){
            img.src = icon_odf_url;
        }
        if(img.complete){
            canvas.drawImage(img,obj.x + 5, obj.y + obj.height / 2 - obj.deviceIconHeight / 2, obj.deviceIconWidth , obj.deviceIconHeight);
        }else{
            img.onload = function(){
                canvas.drawImage(img,obj.x + 5, obj.y + obj.height / 2 - obj.deviceIconHeight / 2, obj.deviceIconWidth , obj.deviceIconHeight);
            }
        }
        //绘制标题
        canvas.font = Device.headerFontSize + "px " + Device.headerFontFamily;
        canvas.fillStyle = Device.headerFontColor;
        canvas.textAlign="left";
        canvasTextAutoLine(obj.name,canvas,obj.x + 10 + obj.deviceIconWidth,obj.y, obj.width - obj.deviceIconWidth - 20, obj.height,Device.headerFontSize + 10,Device.headerFontSize,'middle');
        var port = obj.port;
        port.bodyBackground = Device.portBackground;
        if(port.direct == 'left'){
            port.x = obj.x - Port.width;
        }else{
            port.x = obj.x + obj.width;
        }
        port.y = obj.y;
        port.draw(canvas);
        //绘制上下边框
        var left = obj.x;
        var right = obj.x + obj.width;
        if(port.direct == 'left'){
            left -= Port.width;
        }else{
            right += Port.width;
        }
        canvas.beginPath();
        canvas.strokeStyle = Device.bodyBackground;
        canvas.lineWidth=2;
        canvas.moveTo(left,obj.y);
        canvas.lineTo(right,obj.y);
        canvas.lineTo(right,obj.y + obj.height - 2);
        canvas.lineTo(left,obj.y + obj.height - 2);
        canvas.lineTo(left,obj.y);
        canvas.stroke();
    }
};
//路径
var Path = {
    lineWidth:6,//线的宽度
    arrowLen:20,//箭头耳朵长度,
    goColor:'blue',
    svColor:'red',
    createNew: function(id, startPort, endPort, type_go_sv){
        var path = {};
        path.id = id;
        path.startPort = startPort;
        path.endPort = endPort;
        path.type = type_go_sv;
        path.draw = function(canvas){
            Path.draw(this, canvas);
        };
        return path;
    },
    draw: function(obj,canvas){
        var startPos = obj.startPort.getOutConnectorPos();
        var endPos = obj.endPort.getInConnectorPos();
        var len = Math.sqrt( (startPos.x - endPos.x) * (startPos.x - endPos.x) + (startPos.y - endPos.y) * (startPos.y - endPos.y) );
        var arrowColor = Path.goColor;
        if(obj.type == 'SV'){
            arrowColor = Path.svColor;
        } 
        //画箭头
        drawArrow(canvas, startPos.x , startPos.y, endPos.x, endPos.y, 30, Path.arrowLen, Path.lineWidth, arrowColor);
    }
}
/*
ctx：Canvas绘图环境
fromX, fromY：起点坐标（也可以换成p1，只不过它是一个数组）
toX, toY：终点坐标 (也可以换成p2，只不过它是一个数组)
theta：三角斜边一直线夹角
headlen：三角斜边长度
width：箭头线宽度
color：箭头颜色
*/
function drawArrow(ctx, fromX, fromY, toX, toY,theta,headlen,width,color)
{
    theta = typeof(theta) != 'undefined' ? theta : 30;
    headlen = typeof(theta) != 'undefined' ? headlen : 10;
    width = typeof(width) != 'undefined' ? width : 1;
    color = typeof(color) != 'color' ? color : '#000'; // 计算各角度和对应的P2,P3坐标
    var angle = Math.atan2(fromY - toY, fromX - toX) * 180 / Math.PI, angle1 = (angle + theta) * Math.PI / 180, angle2 = (angle - theta) * Math.PI / 180, topX = headlen * Math.cos(angle1), topY = headlen * Math.sin(angle1), botX = headlen * Math.cos(angle2), botY = headlen * Math.sin(angle2);
    ctx.save();
    ctx.beginPath(); 
    var arrowX = fromX - topX, arrowY = fromY - topY; 
    ctx.moveTo(arrowX, arrowY);
    ctx.moveTo(fromX, fromY); 
    ctx.lineTo(toX, toY); 
    arrowX = toX + topX; 
    arrowY = toY + topY; 
    ctx.moveTo(arrowX, arrowY); 
    ctx.lineTo(toX, toY); 
    arrowX = toX + botX; 
    arrowY = toY + botY; 
    ctx.lineTo(arrowX, arrowY); 
    ctx.strokeStyle = color; 
    ctx.lineWidth = width; 
    ctx.stroke(); 
    ctx.restore(); 
}

/*
str:要绘制的字符串
canvas:canvas对象
initX:绘制字符串起始x坐标
initY:绘制字符串起始y坐标
lineHeight:字行高，自己定义个值即可
fontHeight:字体高度
verticalAlign:文字垂直对齐
*/
function canvasTextAutoLine(str,canvas,rectX,rectY,rectW,rectH,lineHeight,fontHeight,verticalAlign){
    lineHeight = typeof(lineHeight) != 'undefined' ? lineHeight : 20;
    fontHeight = typeof(fontHeight) != 'undefined' ? fontHeight : 20;
    verticalAlign = typeof(verticalAlign) != 'undefined' ? verticalAlign : 'middle';
    var lineWidth = 0;
    var lastSubStrIndex= 0;
    var rowTexts = [];
    
    for(var i=0;i<str.length;i++){ 
        if(i == str.length-1){
            rowTexts.push(str.substr(lastSubStrIndex));
        }else{
            lineWidth += canvas.measureText(str[i]).width;
            lineWidthNext = canvas.measureText(str[i + 1]).width;
            if(lineWidth + lineWidthNext > rectW){
                rowTexts.push(str.substr(lastSubStrIndex,i - lastSubStrIndex + 1));
                lineWidth=0;
                lastSubStrIndex=i+1;
            }
        }
    }

    var startY = rectY;
    if(verticalAlign == 'middle'){
        startY =  rectY + (rectH - rowTexts.length * lineHeight) / 2;
    }else if(verticalAlign == 'top'){
        startY = rectY;
    }else if(verticalAlign == 'bottom'){
        startY = rectY + rectH - rowTexts.length * lineHeight;
    }
    startY += lineHeight / 2;
    for(var i=0;i<rowTexts.length;i++){
        canvas.fillText(rowTexts[i],rectX,startY + i * lineHeight + fontHeight / 2);
    }
}